﻿// (c) Copyright Damian Mehers http://damianblog.com/
// This source is subject to the Microsoft Public License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading;
using MceFM.Last;
using Microsoft.MediaCenter;
using Microsoft.MediaCenter.Hosting;
using Microsoft.MediaCenter.UI;

namespace MceFM.Code {
  public class Player : ModelItem {
    private readonly Settings settings = new Settings();

    private readonly ArrayListDataSet tracks = new ArrayListDataSet();

    public ArrayListDataSet Tracks {
      get {
        foreach(Track track in tracks) {
          Trace.TraceInformation(track.ToString());
        }
        Trace.Flush();
        return tracks;
      }
    }

    public bool CanPlay {
      get {
        Options options = new Options();
        return
          !String.IsNullOrEmpty(options.SavedLastFmPasswordHash) && !String.IsNullOrEmpty(options.SavedLastFmUsername);
      }
    }

    private static string GetMessageFromException(Exception ex) {
      WebException webException = ex as WebException;
      if(webException == null) {
        return ex.Message;
      }
      HttpWebResponse webResponse = webException.Response as HttpWebResponse;
      if(webResponse == null) {
        return ex.Message;
      }
      return webResponse.StatusDescription;
    }

    private static WebClient GetAuthenticatedWebClient() {
      WebClient webClient = new WebClient();

      Options options = new Options();
      webClient.QueryString[Server.USERNAME_QUERY_STRING] = options.SavedLastFmUsername ?? "";
      webClient.QueryString[Server.PASSWORD_HASH_QUERY_STRING] = options.SavedLastFmPasswordHash;

      return webClient;
    }

    public bool Play(PageSession pageSession, object hostObject, string what, string name) {
      if(name.Trim() == "") {
        AddInHost.Current.MediaCenterEnvironment.Dialog("Please enter something to play!",
                                                        settings.DialogTitleForErrors,
                                                        DialogButtons.Ok,
                                                        0,
                                                        true);
        return false;
      }
      IEnumerable<string> initialTrackUrls = null;
      try {
        initialTrackUrls = RequestTracks(what, name);
      } catch(Exception ex) {
        string message = GetMessageFromException(ex);
        Trace.TraceError("UpdateQueue Error: {0}", ex);
        AddInHost.Current.MediaCenterEnvironment.Dialog(message,
                                                        settings.DialogTitleForErrors,
                                                        DialogButtons.Ok,
                                                        0,
                                                        true);
        if(message.StartsWith(settings.LogonFailedStartString)) {
          return true;
        }
      }
      if(initialTrackUrls != null) {
        UpdateQueue(initialTrackUrls);
        Thread.Sleep(2000); // Give the server chance to start downloading
        AddInHost.Current.MediaCenterEnvironment.MediaExperience.GoToFullScreen(); // Shows 'Now Playing'
        AddInHost.Current.ApplicationContext.CloseApplication();
      }
      return false;
    }

    private IEnumerable<string> RequestTracks(string what, string name)
    {
      //Trace.TraceInformation("RequestTracks started");
      WebClient webClient = GetAuthenticatedWebClient();

      string queryStringName;
      string action;

      if(what == settings.PlayArtistMcmlString) {
        queryStringName = Server.ARTIST_QUERY_STRING;
        action = Server.PLAY_ARTIST_ACTION;
      } else {
        queryStringName = Server.TAG_QUERY_STRING;
        action = Server.PLAY_TAG_ACTION;
      }

      webClient.QueryString[queryStringName] = name;
      byte[] bytes = webClient.DownloadData(Util.LocalBaseUrl + action);
      MemoryStream memoryStream = new MemoryStream(bytes);
      StreamReader streamReader = new StreamReader(memoryStream);
      List<string> initialTrackUrls = new List<string>();
      while(!streamReader.EndOfStream) {
        initialTrackUrls.Add(streamReader.ReadLine());
      }
      return initialTrackUrls;
    }


    private static void UpdateQueue(IEnumerable<string> initialTrackUrls) {
      bool queue = false;
      foreach(string initialTrackUrl in initialTrackUrls) {
        AddInHost.Current.MediaCenterEnvironment.PlayMedia(MediaType.Audio, initialTrackUrl, queue);
        queue = true;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="hostObject"></param>
    /// <param name="what"></param>
    /// <param name="name"></param>
    /// <returns>true if a login error occurred</returns>
    public bool Play(object hostObject, string what, string name) {
      return Play(HistoryOrientedPageSession.Current, hostObject, what, name);
    }

    public void ShowQueue(object page) {
      HistoryOrientedPageSession.Current.GoToPage((string)page);
    }
  }
}